//package com.kun.companion.core.http;
//
//import okhttp3.Interceptor;
//import okhttp3.Request;
//import okhttp3.Response;
//import org.jetbrains.annotations.NotNull;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import java.io.IOException;
//
///**
// * HTTP 请求重试拦截器
// * <p>
// * 本拦截器实现了基于状态码和异常类型的请求重试机制，支持以下功能：
// * <ul>
// *   <li>最大尝试次数限制（包含初始请求）</li>
// *   <li>指数退避策略控制重试间隔</li>
// *   <li>可配置重试的HTTP状态码（如429、5xx等）</li>
// *   <li>可配置重试的异常类型（如IO异常、超时异常等）</li>
// * </ul>
// *
// * <h3>配置参数说明：</h3>
// * <pre>
// * - maxAttempts:      总尝试次数（初始请求 + 重试次数）
// * - baseInterval:     基础重试间隔（毫秒）
// * - backoffFactor:    退避系数（每次重试间隔 = baseInterval * backoffFactor^(attempt-1)）
// * - retryableStatusCodes: 可重试的HTTP状态码列表（如429）
// * - retryableExceptions:  可重试的异常类型列表（如SocketTimeoutException.class）
// * </pre>
// *
// * @author gzc
// */
//public class RetryInterceptor implements Interceptor {
//    private static final Logger log = LoggerFactory.getLogger(RetryInterceptor.class);
//    private final ClientConfig.RetryConfig retryConfig;
//
//    /**
//     * 构造方法
//     *
//     * @param retryConfig 重试策略配置，不可为null
//     */
//    public RetryInterceptor(ClientConfig.RetryConfig retryConfig) {
//        this.retryConfig = retryConfig;
//    }
//
//    /**
//     * 拦截HTTP请求并实现重试逻辑
//     *
//     * <h3>执行流程：</h3>
//     * <ol>
//     *   <li>循环尝试请求，直到达到最大尝试次数或请求成功</li>
//     *   <li>每次失败后根据退避策略等待一段时间</li>
//     *   <li>根据响应状态码或异常类型决定是否重试</li>
//     *   <li>最终返回成功响应或抛出最后一次异常</li>
//     * </ol>
//     *
//     * @param chain 拦截器链，用于继续处理请求
//     * @return 最后一次请求的响应对象（成功或不可重试的失败）
//     * @throws IOException 当所有尝试失败且无有效响应时抛出
//     */
//    @NotNull
//    @Override
//    public Response intercept(Chain chain) throws IOException {
//        Request request = chain.request();
//        Response response = null;
//        IOException exception = null;
//        int attempt = 0;
//
//        // 确保至少执行一次请求
//        do {
//            // 非首次尝试时执行退避等待
//            if (attempt > 0) {
//                waitBeforeRetry(attempt);
//            }
//
//            try {
//                // 执行请求
//                response = chain.proceed(request);
//                log.info("请求响应 | 状态码: {}", response.code());
//
//                // 成功响应直接返回
//                if (response.isSuccessful()) {
//                    return response;
//                }
//                // 可重试状态码则关闭响应体后继续循环
//                else if (shouldRetryForStatus(response.code())) {
//                    log.warn("可重试状态码 | Code: {}", response.code());
//                    closeResponse(response);
//                    // 标记为需重试
//                    response = null;
//                }
//                // 不可重试状态码直接返回响应
//                else {
//                    return response;
//                }
//            } catch (IOException e) {
//                exception = e;
//                log.warn("请求异常 | 类型: {}（尝试次数: {}/{}）",
//                        e.getClass().getSimpleName(),
//                        attempt + 1,
//                        retryConfig.getMaxAttempts()
//                );
//                // 不可重试的异常直接抛出
//                if (!shouldRetryForException(e)) {
//                    throw e;
//                }
//            }
//
//            attempt++;
//        } while (shouldRetry(attempt, exception, response));
//
//        // 最终处理：优先抛出异常，其次返回响应，最后抛出兜底错误
//        if (exception != null) {
//            throw exception;
//        }
//        throw new IOException("所有重试尝试均未成功，且未获取有效响应或异常");
//    }
//
//    /**
//     * 检查异常是否需要重试
//     */
//    private boolean shouldRetryForException(Exception e) {
//        return retryConfig.getRetryableExceptions().stream()
//                .anyMatch(clazz -> clazz.isInstance(e));
//    }
//
//    /**
//     * 判断是否应该重试
//     *
//     * @param attempt   当前尝试次数（从0开始）
//     * @param exception 最后一次请求抛出的异常（可能为null）
//     * @param response  最后一次请求的响应（可能为null）
//     * @return true表示需要继续重试，false停止重试
//     */
//    private boolean shouldRetry(int attempt, Exception exception, Response response) {
//        // 检查是否超过最大尝试次数
//        if (attempt >= retryConfig.getMaxAttempts()) {
//            log.debug("达到最大尝试次数: {}", retryConfig.getMaxAttempts());
//            return false;
//        }
//
//        // 异常类型匹配检查
//        if (exception != null) {
//            boolean match = retryConfig.getRetryableExceptions().stream()
//                    .anyMatch(clazz -> clazz.isInstance(exception));
//            log.debug("异常匹配检查结果: {}", match);
//            return match;
//        }
//
//        // 状态码重试检查
//        if (response != null) {
//            boolean shouldRetry = shouldRetryForStatus(response.code());
//            log.debug("状态码 {} 重试检查结果: {}", response.code(), shouldRetry);
//            return shouldRetry;
//        }
//
//        return false;
//    }
//
//    /**
//     * 判断HTTP状态码是否需要重试
//     *
//     * @param statusCode HTTP响应状态码
//     * @return true表示需要重试
//     */
//    private boolean shouldRetryForStatus(int statusCode) {
//        return statusCode == 429 || // 限速状态码
//                (statusCode >= 500 && statusCode <= 599) || // 服务器错误
//                retryConfig.getRetryableStatusCodeList().contains(statusCode); // 自定义可重试状态码
//    }
//
//    /**
//     * 执行重试前的等待（指数退避策略）
//     *
//     * @param attempt 当前尝试次数（从1开始计算退避时间）
//     */
//    private void waitBeforeRetry(int attempt) {
//        try {
//            // 退避时间公式: baseInterval * (backoffFactor)^(attempt-1)
//            long waitTime = (long) (retryConfig.getBaseInterval() *
//                    Math.pow(retryConfig.getBackoffFactor(), attempt - 1));
//            log.info("重试等待 | 第 {} 次重试，等待 {} 毫秒", attempt, waitTime);
//            Thread.sleep(waitTime);
//        } catch (InterruptedException e) {
//            log.warn("重试等待被中断");
//            Thread.currentThread().interrupt(); // 恢复中断状态
//        }
//    }
//
//    /**
//     * 安全关闭响应体
//     *
//     * <p>避免因未关闭响应体导致资源泄漏</p>
//     *
//     * @param response 需要关闭的响应对象
//     */
//    private void closeResponse(Response response) {
//        if (response != null && response.body() != null) {
//            try {
//                response.body().close();
//            } catch (Exception e) {
//                log.debug("关闭响应体时发生非关键异常", e);
//            }
//        }
//    }
//}